<template>
    <div class="bg-f2f3f5 min-w-100 leaveSpace" >
        <div class="flex justify-center mar-x-auto max-w-1200 pad-y-10" >
            <div class="flex justify-center w-100" style="height: calc(100vh - 91px)" >
                <div class="pos-r flex-1 bg-white mar-r-10 pad-10 border-rad-5">
                    <div class="flex mar-y-15 align-center">
                        <SvgIcons iconClass="privateMsg_icon" class="mar-r-5 color-1e9fff" style="font-size: 40px;" />
                        <span class="color-1e9fff font-18">私信</span>
                    </div>

                    <div class="font-14 mar-l-5 color-999999 mar-y-10">
                        <span>共</span>
                        <span class="color-1e9fff"> {{ friendList.length }} </span>
                        <span>个好友</span>
                    </div>

                    <div :class="'friend_list ' + (item.active ? 'nav-item-active' : 'nav-item-default')"
                        v-for="item in friendList"
                        :key="item.userId + '-' + item.lastMessageTime"
                        @click="selectFriend(item)"
                        @dblclick="goLatest(item)" 
                    >
                        <div class="w-px-50 h-50 overflow-hidden radius-50 mar-r-15 flex justify-center align-center defaultBorder">
                            <img :src="getAuthorAvatar(item)" class="w-100 h100 img-normal" />
                        </div>

                        <div class="flex-1">
                            <div class="flex align-center">
                                <div class="font-16">{{ item.nickName || item.username }}</div>
                                <el-badge :value="item.noReadCount" class="noReadCount" :hidden="item.noReadCount === 0">
                                </el-badge>
                            </div>

                            <div class="flex align-center justify-between text-nowrap">
                                <div class="lastMsg font-14">
                                    <span v-if="item.lastMessage && item.lastMessage.startsWith('[图片]')">[图片]</span>
                                    <span v-else>{{ item.lastMessage }}</span>
                                </div>
                                <div class="color-8a919f font-12">{{ formatDatetime(item.lastMessageTime) }}</div>
                            </div>
                        </div>
                    </div> 

                    <router-link
                        to="/"
                        class="pos-a b-10 color-1e9fff font-14 bg-f0f4ff pad-y-10 border-rad-5 text-dec-none text-nowrap"
                        style="width: calc(100% - 20px);"
                    >
                        <span class="mar-x-5">&lt;</span>
                        <span>返回首页</span>
                    </router-link>
                </div>

                <div class="flex-3 bg-white border-rad-5">
                    <div v-if="friendList.length === 0 || !currentFriendId || !currentFriend" class="h100 bg-white flex justify-center align-center ">
                        <SvgIcons iconClass="emptyChat_icon" class="color-1e9fff" style="font-size: 150px;" />
                    </div>

                    <div v-else class="flex flex-column h100">
                        <div v-loading="loading" v-if="loading" style="padding: 10px; overflow-y: auto; height: 65vh"></div>
                        <div v-loading="isLoadingMore" v-else-if="isLoadingMore" style="padding: 10px; overflow-y: auto; height: 65vh"></div>

                        <div 
                            v-else-if="chatList.length === 0" 
                            class="empty-chat-bg flex mar-t-30 justify-center not-copy"
                            :style="{ backgroundImage: `url(${logoImg})` }"
                        >
                            您还没有聊天记录！
                        </div>
                        
                        <div v-else class="pad-10 overflow-y-auto" ref="record"
                            :style="{
                                minHeight: '300px',
                                flex: '1 1 0',
                            }"
                        >
                            <div v-if="noMoreHistory" class="flex mar-t-30 justify-center color-cccccc not-copy">~没有更多记录</div>

                            <div
                                v-for="(item, index) in chatList"
                                :key="index"
                            >
                                <div :class="'flex mar-t-10 w-100 '+ (item.senderId === userInfo.id ? 'justify-end' : '')">
                                    <div v-if="item.senderId === userInfo.id" class="flex">
                                        <div
                                            @contextmenu.prevent="showMenu($event, item)"
                                        >
                                            <div v-if="isImageMessage(item)" class="image-message">
                                                <img 
                                                    :src="getImageUrl(item)" 
                                                    class="chat-image" 
                                                    @click="previewImage(item)"
                                                    alt="图片"
                                                />
                                            </div>
                                            <div v-else class="flex align-center self">
                                                <span>{{ item.content }}</span>
                                            </div>
                                        </div>

                                        <ul v-if="menuVisible"
                                            :style="{left: menuX + 'px', top: menuY + 'px'}"
                                            class="right-menu"
                                        >
                                            <li @click="doRecall($event,item)">撤回</li>
                                            <li @click="menuVisible = false">取消</li>
                                        </ul>

                                        <div class="overflow-hidden h-40 w-px-40 radius-50 mar-l-10 defaultBorder">
                                            <img :src="getAvatar(item)" class="w-100 h100 img-normal" >
                                        </div>
                                    </div>

                                    <div v-else class="flex">
                                        <div class="overflow-hidden h-40 w-px-40 radius-50 mar-r-10 defaultBorder">
                                            <img :src="getAvatar(item)" class="w-100 h100 img-normal" >
                                        </div>

                                        <div v-if="isImageMessage(item)" class="image-message">
                                            <img 
                                                :src="getImageUrl(item)" 
                                                class="chat-image" 
                                                @click="previewImage(item)"
                                                alt="图片"
                                            />
                                        </div>
                                        <div v-else class="flex align-center other">
                                            <span>{{ item.content }}</span>
                                        </div>
                                    </div>
                                </div>

                                <div
                                    v-if="checkDate(item, index)"
                                    class="flex justify-center color-999999 mar-y-20 font-12"
                                >
                                    {{ formatDatetime(index <= chatList.length - 1 ? chatList[index + 1].createTime : '') }}

                                </div>
                            </div>
                        </div>

                        <div class="splitter" @mousedown="startDrag($event)">
                            <Lines  h="2px" w="100%" bg="#f2f3f5"/>
                        </div>

                        <div class="mar-t-5 input-area pad-10" ref="inputArea">
                            <div class="flex align-center" style="flex: 0 0 auto;">
                                <span class="cur-pointer mar-r-10">{{ emoji }}</span>

                                <!-- 截屏裁剪组件 -->
                                <ScreenCapture 
                                    @capture-success="handleCaptureSuccess"
                                    @capture-cancel="handleCaptureCancel"
                                    @capture-error="handleCaptureError"
                                />
                                
                                <!-- 图片上传按钮 -->
                                <el-upload
                                    ref="imageUpload"
                                    :action="upload.action"
                                    :name="upload.name"
                                    :accept="upload.accept"
                                    :limit="upload.limit"
                                    :headers="uploadHeaders"
                                    :show-file-list="false"
                                    :on-success="handleImageSuccess"
                                    :on-error="handleImageError"
                                    :on-progress="handleImageProgress"
                                    :before-upload="beforeImageUpload"
                                >
                                    <SvgIcons iconClass="photo_icon" class="cur-pointer hoverClass" />
                                </el-upload>
                            </div>

                            <!-- 图片预览区域 -->
                            <div v-if="upload.imagePreview" class="image-preview-wrapper mar-y-10">
                                <div class="image-preview pos-r">
                                    <img :src="upload.imagePreview" class="preview-image" />
                                    <div class="preview-actions">
                                        <el-button size="mini" type="danger" @click="removeImagePreview">删除</el-button>
                                    </div>
                                </div>
                            </div>

                            <div class="flex mar-t-5 h100" style="flex: 1 1 0;">
                                <textarea
                                    v-model.trim="content"
                                    placeholder="请输入聊天内容"
                                    class="chatInput"
                                    @keydown.enter="handleKeydown($event)"
                                ></textarea>
                            </div>

                            <div class="send-bar">
                                <el-button type="primary" size="small" @click="send()" :disabled="!content && !upload.imagePreview">
                                    发送
                                </el-button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import Lines from "@/components/Lines/index"
	import SvgIcons from '@/components/SvgIcons/index'
    import ScreenCapture from '@/components/ScreenCapture/index'
    import ImageEditor from '@/components/ScreenCapture/ImageEditor'
    import moment from 'moment'
    import Utils from '@/utils/utils'

    import { mapState } from 'vuex'
    import { getChatRecord, revokeMsg } from '@/apis/user'
    import { checkLogin } from '@/utils/lib'

    export default {
        name: 'PrivateMessage',

        components: {
            Lines,
            SvgIcons,
            ScreenCapture,
            ImageEditor,
        },

        watch: {
            // 监听完整路由对象
			'$route': {
				handler(to, from) {
					if (to.path === '/privateMessage') {
                        if (this.$route.query && JSON.stringify(this.$route.query) !== '{}') {
                                // 点击用户文章私信进入,根据作者的id进行定位好友(点击小铃铛下的未读消息列表,如果是私信,就进入聊天界面)
                                this.$store.dispatch('user/getFriendList').then(() => {
                                    this.$store.commit('user/setCurrentFriend', this.friendList.find(item => item.userId === JSON.parse(to.query.userId)))
                                }).catch(() => {
                                    this.$store.commit('user/setCurrentFriend', {})
                                })
                        } else {
                            // 如果存在好友,定位第一个好友
                            if (this.friendList.length > 0) {
                                if (this.currentFriend) {
                                    this.$store.dispatch('user/getFriendList').then(() => {
                                        this.$store.commit('user/setCurrentFriend', this.friendList.find(item => item.userId === this.currentFriendId))
                                    }).catch(() => {
                                        this.$store.commit('user/setCurrentFriend', {})
                                    })
                                } else {
                                    this.$store.dispatch('user/getFriendList').then(() => {
                                        this.$store.commit('user/setCurrentFriend', this.friendList[0])
                                    }).catch(() => {
                                        this.$store.commit('user/setCurrentFriend', {})
                                    })
                                }
                            }
                        }
                    }
				},
				immediate: true,
				deep: true
			}
        },

        computed: {
            ...mapState({
                isLogin: state => state.user.isLogin,
                userInfo: state => state.user.userInfo, // 用户信息
                token: state => state.user.token,  // token
                defaultAvatar: state => state.user.defaultAvatar, // 默认头像
                friendList: state => state.user.friendList, // 好友列表
                currentFriendId: state => state.user.currentFriendId, // 当前聊天对象id
                currentFriend: state => state.user.currentFriend, // 当前聊天对象
                noReadMsgList: state => state.user.noReadMsgList, // 未读消息列表
                noReadMsgCount: state => state.user.noReadMsgCount, // 未读消息数量
                currentMenuId: state => state.articleManage.currentMenuId, // 当前菜单id
            }),

            // 上传图片请求头
            uploadHeaders() {
                return {
                    'Authorization': 'Bearer ' + this.token
                }
            },

            // 格式化当前时间
            formatDatetime() {
                return (dateTime) => {
                    if (!dateTime) return ''
                    
                    const now = moment()
                    const targetTime = moment(dateTime)
                    
                    // 如果时间差小于60秒，显示"刚刚"，否则使用fromNow
                    return now.diff(targetTime, 'seconds') < 60 ? '刚刚' : targetTime.fromNow()
                }
            },

            // 获取好友头像
            getAuthorAvatar() {
                return (item) => {
                    return item.avatar ? process.env.VUE_APP_IMG_BASE_API + item.avatar : this.defaultAvatar
                }
            },

            // 获取聊天对象头像
            getAvatar() {
                return (item) => {
                    return item.senderAvatar ? process.env.VUE_APP_IMG_BASE_API + item.senderAvatar : this.defaultAvatar
                }
            },

            // 校验时间差，获取两段对话的时间间隔
            checkDate() {
                return (row, index) => {
                    let result = false

                    if (row.createTime) {
                        let currentDatestamp = new Date(row.createTime).getTime() // 当前时间戳

                        this.chatList.forEach((item, i) => {
                            if (index + 1 === i) {
                                let nextDatestamp = new Date(item.createTime).getTime()
                                if (nextDatestamp - currentDatestamp > 10 * 60 * 1000) {
                                    result = true
                                }
                            }
                        })
                    }

                    return result
                }
            }
        },

        data() {
            return {
                logoImg: require('@/assets/images/logo.png'),
                loading: false, // 局部加载状态
                nickName: '', // 用户昵称
                avatar: '', // 用户头像
                username: '', // 用户名
                emoji: '😊',
                content: '', // 输入框内容
                search: '', // 选中的表情
                chatList: [], // 聊天记录
                scrollTimer: null, // 滚动定时器
                isLoadingMore: false,    // 正在拉取更早记录
                noMoreHistory: false,    // 已无更早记录
                isScrollingToBottom: false, // 是否正在滚动到底部
                currentPage: 1, // 当前页聊天记录
                pageSize: 20, // 每页显示条数
                lastClickFriendId: null, // 上次点击的好友
                menuVisible: false, // 菜单是否显示
                menuX: 0, // 菜单x坐标
                menuY: 0, // 菜单y坐标
                activeMsg: null,   // 当前右键消息
                message: null, // 当前消息
                timer: null, // 定时器
                dragging: false, // 是否正在拖拽
                startY: 0, // 拖拽开始时y坐标
                startInputH: 0, // 输入框高度

                isSending: false, // 发送状态控制
                pendingMessages: [], // 待发送消息队列

                // 截屏相关
                editorVisible: false, // 图片编辑器是否显示
                capturedImage: '', // 截屏图片

                // 图片上传相关数据
                upload: {
                    action: process.env.NODE_ENV === 'development' ? process.env.VUE_APP_PROD_UPLOAD_BASE_API : process.env.VUE_APP_PROD_UPLOAD_BASE_API,
                    name: 'file',
                    accept: '.jpg,.png,.jpeg,.gif,.bmp,.webp',
                    limit: 1,
                    imagePreview: '', // 图片预览URL
                    uploadedImageUrl: '', // 上传成功的图片URL
                    loading: false, // 上传加载状态
                },
            }
        },

        destroyed() {
            this.$store.commit('articleManage/setCurrentMenuId', null) // 重置当前菜单id
            window.removeEventListener('onMessage', this.handleWsMessage) // 移除服务端消息监听
            const r = this.$refs.record
            if (r) r.removeEventListener('scroll', this.handleScroll) // 移除滚动监听
        },

        mounted() {
            // 判断是否登录,没有登录则跳转回首页
            if (!checkLogin()) {
                Utils.popUpMsg('warning', '请先登录！', 3000)
                this.$router.push('/')
                return
            }
            this.$store.commit('articleManage/setCurrentMenuId', 5)

            window.addEventListener('onMessage', this.handleWsMessage) // 监听服务端消息
            const r = this.$refs.record
            if (r) r.addEventListener('scroll', this.handleScroll)

            // 获取聊天记录
            if (this.friendList.length === 0 || !this.currentFriendId || !this.currentFriend) return
            this.findChatRecord()
        },

        methods: {
            // 截屏成功处理
            handleCaptureSuccess(imageData) {
                this.capturedImage = imageData
                this.editorVisible = true
            },

            // 截屏取消
            handleCaptureCancel() {
                Utils.popUpMsg('info', '已取消截屏', 1500)
            },

            // 截屏错误
            handleCaptureError(error) {
                console.error('截屏错误:', error)
                Utils.popUpMsg('error', '截屏失败，请重试', 3000)
            },

            // 图片更新
            handleImageUpdated(imageData) {
                this.capturedImage = imageData
            },

            // 确认编辑
            handleEditConfirm() {
                this.upload.imagePreview = this.capturedImage
                this.upload.uploadedImageUrl = this.capturedImage // 如果是base64，可能需要上传到服务器
                this.editorVisible = false

                // 如果是base64图片，可能需要先上传到服务器
                this.uploadBase64Image(this.capturedImage)
            },

            // 上传base64图片到服务器
            uploadBase64Image(base64Data) {
                // 这里实现base64图片上传逻辑
                // 将base64转换为Blob并上传
                const blob = this.base64ToBlob(base64Data)
                const formData = new FormData()
                formData.append('file', blob, 'screenshot.png')
            },

            // base64转Blob
            base64ToBlob(base64Data) {
                const arr = base64Data.split(',')
                const mime = arr[0].match(/:(.*?);/)[1]
                const bstr = atob(arr[1])
                let n = bstr.length
                const u8arr = new Uint8Array(n)
                
                while (n--) {
                    u8arr[n] = bstr.charCodeAt(n)
                }

                return new Blob([u8arr], { type: mime })
            },

            // 判断是否为图片消息
            isImageMessage(item) {
                // 方法1：通过消息类型判断
                if (item.messageType === 'image') {
                    return true
                }
                // 方法2：通过内容格式判断（兼容旧数据）
                if (item.content && item.content.startsWith('[图片]')) {
                    return true
                }
                // 方法3：通过图片URL字段判断
                if (item.imageUrl) {
                    return true
                }
                return false
            },

            // 图片预览方法，处理跨域问题
            previewImage(item) {
                const imageUrl = this.getImageUrl(item)
                if (!imageUrl) return

                // 创建预览层
                const overlay = document.createElement('div')
                overlay.style.cssText = `
                    position: fixed;
                    top: 0;
                    left: 0;
                    width: 100vw;
                    height: 100vh;
                    background: rgba(0, 0, 0, 0.9);
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    z-index: 9999;
                    cursor: zoom-out;
                `

                // 创建图片容器
                const imgContainer = document.createElement('div')
                imgContainer.style.cssText = `
                    position: relative;
                    max-width: 90vw;
                    max-height: 90vh;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                `

                // 创建加载状态
                const loadingDiv = document.createElement('div')
                loadingDiv.style.cssText = `
                    color: white;
                    font-size: 16px;
                    padding: 20px;
                `
                loadingDiv.textContent = '图片加载中...'
                imgContainer.appendChild(loadingDiv)

                // 创建图片元素 - 使用代理方式解决跨域
                const img = new Image()

                // 使用代理方式加载图片
                const proxyImageUrl = this.getProxyImageUrl(imageUrl)
                img.src = proxyImageUrl

                img.style.cssText = `
                    max-width: 100%;
                    max-height: 100%;
                    object-fit: contain;
                    border-radius: 4px;
                    display: none; /* 初始隐藏 */
                `
                // 图片加载成功
                img.onload = () => {
                    loadingDiv.remove()
                    img.style.display = 'block'
                }

                // 图片加载失败处理 - 尝试直接加载原图
                img.onerror = () => {
                    img.src = imageUrl
                    
                    img.onload = () => {
                        loadingDiv.remove()
                        img.style.display = 'block'
                    }

                    img.onerror = () => {
                        loadingDiv.innerHTML = `
                            <div style="text-align: center; color: #fff;">
                                <div style="margin-bottom: 10px;">图片加载失败</div>
                                <div style="font-size: 12px; opacity: 0.7;">可能由于跨域限制无法预览</div>
                            </div>
                        `
                    }
                }

                // 创建关闭按钮
                const closeBtn = document.createElement('button')
                closeBtn.innerHTML = '×'
                closeBtn.style.cssText = `
                    position: absolute;
                    top: -50px;
                    right: -50px;
                    width: 40px;
                    height: 40px;
                    background: rgba(255, 255, 255, 0.2);
                    border: none;
                    border-radius: 50%;
                    color: white;
                    font-size: 24px;
                    cursor: pointer;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    transition: background 0.3s;
                    z-index: 10000;
                `

                closeBtn.addEventListener('mouseenter', () => {
                    closeBtn.style.background = 'rgba(255, 255, 255, 0.4)'
                })

                closeBtn.addEventListener('mouseleave', () => {
                    closeBtn.style.background = 'rgba(255, 255, 255, 0.2)'
                })

                // 关闭函数
                const closePreview = () => {
                    if (document.body.contains(overlay)) {
                        document.body.removeChild(overlay)
                    }
                    document.removeEventListener('keydown', handleKeydown)
                }

                // 点击遮罩层关闭
                overlay.addEventListener('click', (e) => {
                    if (e.target === overlay) {
                        closePreview()
                    }
                })

                // ESC 键关闭
                const handleKeydown = (e) => {
                    if (e.key === 'Escape') {
                        closePreview()
                    }
                }

                closeBtn.addEventListener('click', closePreview)
                document.addEventListener('keydown', handleKeydown)

                // 组装元素
                imgContainer.appendChild(img)
                imgContainer.appendChild(closeBtn)
                overlay.appendChild(imgContainer)
                document.body.appendChild(overlay)

                // 阻止事件冒泡到遮罩层
                imgContainer.addEventListener('click', (e) => {
                    e.stopPropagation()
                })
            },

            // 添加图片代理方法 - 解决跨域问题
            getProxyImageUrl(originalUrl) {
                // 对于base64或同源图片直接返回
                if (originalUrl.startsWith('data:') || originalUrl.startsWith('/') || originalUrl.includes(window.location.hostname)) {
                    return originalUrl
                }

                // 尝试使用images.weserv.nl代理（第三方CORS代理）
                try {
                    const url = new URL(originalUrl)
                    // 使用第三方CORS代理
                    return `https://images.weserv.nl/?url=${encodeURIComponent(url.hostname + url.pathname)}`
                } catch (e) {
                    // 如果URL解析失败，直接返回原URL
                    return originalUrl
                }
            },

            // 修改获取图片URL的方法，确保返回完整URL
            getImageUrl(item) {
                if (item.imageUrl) {
                    // 如果已经是完整URL，直接返回
                    if (item.imageUrl.startsWith('http')) {
                        return item.imageUrl
                    }
                    // 否则添加基础URL
                    return process.env.VUE_APP_IMG_BASE_API + item.imageUrl
                }
                if (item.content && item.content.startsWith('[图片]')) {
                    const url = item.content.replace('[图片]', '')
                    if (url.startsWith('http')) {
                        return url
                    }
                    return process.env.VUE_APP_IMG_BASE_API + url
                }

                return ''
            },

            // 图片上传前的验证
            beforeImageUpload(file) {
                const isLt5M = file.size / 1024 / 1024 < 5
                if (!isLt5M) {
                    Utils.popUpMsg('error', '上传图片大小不能超过 5MB!', 3000)
                    return false
                }
                
                // 显示预览
                const reader = new FileReader()
                reader.onload = (e) => {
                    this.upload.imagePreview = e.target.result
                }
                reader.readAsDataURL(file)
                
                return true
            },

            // 图片上传成功
            handleImageSuccess(response, file) {
                this.upload.loading = false
                
                if (response.code === 200) {
                    this.upload.uploadedImageUrl = response.data.url || response.data
                    // 移除成功弹窗：Utils.popUpMsg('success', '图片上传成功!', 1500)
                } else {
                    Utils.popUpMsg('error', response.msg || '图片上传失败', 3000)
                    this.removeImagePreview()
                }
            },

            // 图片上传错误
            handleImageError(error, file) {
                this.upload.loading = false
                Utils.popUpMsg('error', '图片上传失败，请重试', 3000)
                this.removeImagePreview()
            },

            // 图片上传进度
            handleImageProgress(event, file) {
                this.upload.loading = true
            },

            // 移除图片预览
            removeImagePreview() {
                this.upload.imagePreview = ''
                this.upload.uploadedImageUrl = ''
                this.upload.loading = false
                this.$refs.imageUpload.clearFiles()
            },

            // 开始拖拽
            startDrag(e) {
                this.dragging = true
                this.startY = e.clientY
                this.startInputH = this.$refs.inputArea.clientHeight

                document.addEventListener('mousemove', this.onDrag)
                document.addEventListener('mouseup', this.stopDrag)
                // 防止拖动时选中文本
                e.preventDefault()
            },
            
            // 拖拽
            onDrag(e) {
                if (!this.dragging) return
                const dy = e.clientY - this.startY          // 鼠标纵向移动量
                const newH = Math.max(60, this.startInputH - dy) // 最小 60px
                this.$refs.inputArea.style.flexBasis = newH + 'px'
            },

            // 停止拖拽
            stopDrag() {
                this.dragging = false
                document.removeEventListener('mousemove', this.onDrag)
                document.removeEventListener('mouseup', this.stopDrag)
            },

            // 获取历史聊天记录
            loadHistory() {
                if (this.loadingHistory || this.noMoreHistory) return

                const r = this.$refs.record
                if (!r) return

                this.loadingHistory = true
                const params = {
                    recipientId: this.currentFriendId,
                    currentPage: this.currentPage,
                    pageSize: this.pageSize
                }

                getChatRecord(params).then(res => {
                    this.loadingHistory = false
                    if (res.code === 200 && res.data.rows.length) {
                        // 保存当前滚动位置相关信息
                        const previousScrollHeight = r.scrollHeight

                        // 添加新记录到开头
                        this.chatList.unshift(...res.data.rows.reverse())

                        this.$nextTick(() => {
                            const r = this.$refs.record
                            if (!r) return

                            // 计算新内容的高度并平滑滚动
                            const newScrollHeight = r.scrollHeight
                            const heightDifference = newScrollHeight - previousScrollHeight

                            // 设置滚动位置到新内容开始的地方
                            r.scrollTop = heightDifference
                        })

                        this.noMoreHistory = res.data.rows.length < this.pageSize
                        this.currentPage++
                    } else {
                        this.noMoreHistory = true
                    }
                }).catch(() => {
                    this.loadingHistory = false
                })
            },

            // 查找聊天记录
            findChatRecord() {
                let params = {
                    recipientId: this.currentFriendId,
                    currentPage: this.currentPage,
                    pageSize: this.pageSize,
                }

                this.loading = true
                getChatRecord(params).then(res => {
                    this.loading = false
                    if (res.code == 200) {
                        let data = res.data.rows.reverse() // 将数据反过来
                        this.chatList = data

                        this.$nextTick(() => {
                            const r = this.$refs.record
                            if (!r) return
                            r.scrollTo({
                                top: r.scrollHeight,
                                behavior: 'smooth'
                            })
                        })

                        // 判断是否还有更早数据
                        this.noMoreHistory = res.data.rows.length < this.pageSize
                        this.currentPage = 2 // 下一次要请求的页码
                    } else {
                        this.loading = false
                    }
                }).catch(err => {
                    this.loading = false
                })
            },

            // 选择聊天的好友对象
            selectFriend(row) {
                clearTimeout(this.timer)

                this.timer = setTimeout(() => {
                    // 切换好友时重置状态
                    this.currentPage = 1
                    this.isLoadingHistory = false

                    this.$store.commit('user/setCurrentFriend', row) // 设置当前聊天对象
                    // 更新好友列表未读消息和数量
                    this.$store.dispatch('user/updateFriendMsgState', {senderId: row.userId}).then(() => {
                        this.$store.dispatch('user/getNoReadMsgList')
                        this.$store.dispatch('user/getNoReadMsgCount')
                    })
                    this.$store.commit('user/setNoReadCount', row)

                    // 标记上一个点击的好友ID
                    const previousFriendId = this.lastClickFriendId
                    this.lastClickFriendId = row.userId
                    if (this.currentFriendId === row.userId && previousFriendId === row.userId) return
                        this.noMoreHistory = false
                        this.findChatRecord()
                }, 200)
            },

            // 滚动到聊天区域底部
            scrollToBottom() {
                const r = this.$refs.record
                if (!r) return
                r.scrollTop = r.scrollHeight
                this.isScrollingToBottom = false
            },

            // 处理滚动事件
            handleScroll(event) {
                clearTimeout(this.scrollTimer)
                this.scrollTimer = setTimeout(() => {
                    const scrollElement = event.target
                    const scrollThreshold = 50

                    if (scrollElement.scrollTop <= scrollThreshold && 
                        !this.isLoadingHistory && 
                        !this.noMoreHistory) {
                        this.loadHistory()
                    }
                }, 100)
            },

            // 双击好友列表项回到最新消息
            goLatest(row) {
                // 如果双击的好友不是当前聊天对象，先切换到该好友
                if (this.currentFriendId !== row.userId) {
                    this.selectFriend(row)
                } else {
                    // 如果是当前聊天对象，直接滚动到底部
                    this.scrollToBottom()
                }
            },

            // 监听服务端消息
            handleWsMessage(message) {
                // 消息发送结果通知
                if (message && message.detail.type === 'chat_notice') {
                    this.handleSendMsg(message) // 发送消息处理
                }

                // 聊天消息处理
                if (message && message.detail.type === 'chat') {
                    this.handleChatMsg(message)
                }
            },

            // 聊天消息处理（接收消息）
            handleChatMsg(message) {
                let data = message.detail.data
                let msg = {
                    chatId: data.chatId,
                    content: data.content,
                    createTime: data.createTime,
                    senderAvatar: data.senderAvatar,
                    senderId: data.senderId,
                    senderNickName: data.senderNickName,
                    senderUsername: data.senderUsername,
                    type: 1,
                    messageType: data.messageType || 'text',
                    imageUrl: data.imageUrl
                }

                // 如果是图片消息但没有imageUrl，尝试从content中提取
                if (msg.messageType === 'image' && !msg.imageUrl && msg.content.startsWith('[图片]')) {
                    msg.imageUrl = msg.content.replace('[图片]', '')
                }

                // 如果接收到的消息是当前聊天对象
                if (data.senderId === this.currentFriendId) {
                    this.chatList.push(msg)

                    // 立即更新当前好友的最后一条消息
                    this.updateCurrentFriendLastMessage(msg)

                    this.$store.dispatch('user/updateFriendMsgState', {senderId: this.currentFriendId})
                    this.updateFriendMsg(data, true)

                    this.$nextTick(() => {
                        const r = this.$refs.record
                        if (!r) return
                        r.scrollTop = r.scrollHeight
                    })
                } else {
                    this.updateFriendMsg(data, false)
                }
            },

            // 更新好友列表未读消息
            updateFriendMsg(data, flag) {
                let querys = {
                    userId: data.senderId,
                    lastMessageTime: data.createTime,
                    lastMessage: data.content,
                    isSender: flag, // flag: boolean, true 自己发的，false 对方发的
                }

                this.$store.commit('user/setNoReadCount', querys)
            },

            // 发送消息处理
            handleSendMsg(message) {
                if (message.detail.data && this.message) {
                    try {
                        // 消息发送成功，添加后端返回的消息id
                        this.message.chatId = message.detail.data.chatId
                        this.message.createTime = message.detail.data.createTime

                        // 将消息添加到列表中
                        this.chatList.push({...this.message})

                        // 立即更新当前好友的最后一条消息
                        this.updateCurrentFriendLastMessage(this.message)

                        // 发送后滚动到底部
                        this.$nextTick(() => {
                            const r = this.$refs.record
                            if (r) {
                                r.scrollTop = r.scrollHeight
                            }
                        })

                        // 清空临时消息
                        this.message = null

                    } catch (error) {
                        console.error('处理发送消息错误:', error)
                        Utils.popUpMsg('error', '消息发送处理失败', 3000)
                    }
                } else {
                    // 消息发送失败
                    Utils.popUpMsg('error', message.detail.msg || '消息发送失败', 3000)
                    this.message = null
                }
            },

            // 更新当前好友的最后一条消息
            updateCurrentFriendLastMessage(msg) {
                if (!this.currentFriend) return

                const lastMessage = msg.messageType === 'image' ? '[图片]' : msg.content

                // 直接更新当前好友对象
                this.currentFriend.lastMessage = lastMessage
                this.currentFriend.lastMessageTime = msg.createTime

                // 减少未读计数
                if (this.currentFriend.noReadCount > 0) {
                    this.currentFriend.noReadCount = 0
                }
                
                // 触发好友列表重新渲染
                this.$forceUpdate()
            },

            // 发送消息
            send() {
                if (this.isSending) {
                    Utils.notifyPopUpMsg('warning', '正在发送中，请稍候...', '提示', 1000)
                    return
                }

                // 检查是否有内容可发送
                const hasImage = this.upload.uploadedImageUrl
                const hasText = this.content && this.content.trim()

                if (!hasImage && !hasText) {
                    Utils.notifyPopUpMsg('info', '不能发送空白信息！', '提示', 1000)
                    return
                }

                this.isSending = true

                try {
                    // 先发送图片
                    if (hasImage) {
                        this.sendImageMessage()
                    }

                    // 再发送文字
                    if (hasText) {
                        if (hasImage) {
                            // 图片和文字都有，延迟发送文字
                            setTimeout(() => {
                                this.sendTextMessage()
                                this.isSending = false
                            }, 500)
                        } else {
                            // 只有文字
                            this.sendTextMessage()
                            this.isSending = false
                        }
                    } else {
                        // 只有图片
                        this.isSending = false
                    }
                } catch (error) {
                    console.error('发送消息错误:', error)
                    Utils.popUpMsg('error', '消息发送失败', 3000)
                    this.isSending = false
                }
            },

            // 发送文本消息 - 返回 Promise
            sendTextMessage() {
                return new Promise((resolve) => {
                    if (!this.content || !this.content.trim()) {
                        resolve()
                        return
                    }

                    let data = {
                        type: 'chat',
                        data: { 
                            content: this.content.trim(), 
                            recipientId: this.currentFriendId,
                            messageType: 'text'
                        }
                    }

                    const textMessage = {
                        chatId: null,
                        content: this.content.trim(),
                        createTime: '',
                        isRevoke: 0,
                        recipientId: this.currentFriendId,
                        senderAvatar: this.userInfo.avatar,
                        senderId: this.userInfo.id,
                        senderNickName: this.userInfo.nickName,
                        senderUsername: this.userInfo.username,
                        state: 1,
                        type: 1,
                        messageType: 'text'
                    }

                    this.message = textMessage
                    const contentToSend = this.content
                    this.content = ''
                    
                    window.dispatchEvent(new CustomEvent('handleSendChat', { detail: data }))
                    resolve()
                })
            },

            // 发送图片消息 - 返回 Promise
            sendImageMessage() {
                return new Promise((resolve) => {
                    if (!this.upload.uploadedImageUrl) {
                        resolve()
                        return
                    }

                    let data = {
                        type: 'chat',
                        data: { 
                            content: `[图片]${this.upload.uploadedImageUrl}`,
                            recipientId: this.currentFriendId,
                            messageType: 'image',
                            imageUrl: this.upload.uploadedImageUrl
                        }
                    }

                    const imageMessage = {
                        chatId: null,
                        content: `[图片]${this.upload.uploadedImageUrl}`,
                        createTime: '',
                        isRevoke: 0,
                        recipientId: this.currentFriendId,
                        senderAvatar: this.userInfo.avatar,
                        senderId: this.userInfo.id,
                        senderNickName: this.userInfo.nickName,
                        senderUsername: this.userInfo.username,
                        state: 1,
                        type: 1,
                        messageType: 'image',
                        imageUrl: this.upload.uploadedImageUrl,
                        imagePreview: this.upload.imagePreview
                    }

                    this.message = imageMessage
                    this.removeImagePreview()
                    
                    window.dispatchEvent(new CustomEvent('handleSendChat', { detail: data }))
                    resolve()
                })
            },
            // 添加表情
            insert(a) {
                this.content += a
            },

            // 键盘事件处理
            handleKeydown(e) {
                if (e.shiftKey && e.key === 'Enter') {
                    const { selectionStart, selectionEnd } = e.target
                    const before = this.content.slice(0, selectionStart)
                    const after  = this.content.slice(selectionEnd)
                    this.content = `${before}\n${after}`

                    this.$nextTick(() => {
                        e.target.selectionStart = e.target.selectionEnd = selectionStart + 1
                    })
                    return
                }

                if (e.key === 'Enter') {
                    e.preventDefault()
                    this.send()
                }
            },

            // 显示撤回菜单
            showMenu(e, msg) {
                // 只允许自己且 60s 内
                let msgTs = moment(msg.createTime).valueOf()
                if (Date.now() - msgTs > 60000) return
                if (msg.senderId !== this.userInfo.id) return

                this.menuX = e.pageX
                this.menuY = e.pageY
                this.activeMsg = msg
                this.menuVisible = true
                // 点别处关闭
                const hide = () => {
                    this.menuVisible = false
                    document.removeEventListener('click', hide)
                }

                this.$nextTick(() => document.addEventListener('click', hide))
            },

            // 撤回回调
            doRecall(e, row) {
                let msgTs = moment(row.createTime).valueOf()

                if (Date.now() - msgTs > 60 * 1000) {
                    Utils.popUpMsg('error', '撤回消息已超过一分钟', 3000)
                    return
                }

                revokeMsg({msgId: row.chatId}).then(res => {
                    if (res.code === 200) {
                        this.chatList.splice(this.chatList.findIndex(m => m.chatId === row.chatId), 1)
                        Utils.notifyPopUpMsg('success', '撤回消息成功', '提示', 1000)
                    } else {
                        Utils.popUpMsg('error', '撤回失败', 1500)
                    }
                }).catch(() => {
                })
            },
        },
    }
</script>

<style lang="scss" scoped>
    @media screen and (max-width: 750px) {
		.leaveSpace {
			padding-left: 0;
			padding-right: 0;
		}
	}

    @media screen and (min-width: 750px) {
        .leaveSpace {
            padding-left: 10px;
            padding-right: 10px;
        }
    }
    .chatInput {
        outline: none;
        border: none;
        box-sizing: border-box;
        font-family: "微软雅黑";
        width: 100%;
        height: 100%;           /* 填满父级 */
        resize: none;           /* 禁止用户手动拖角 */
        padding: 6px;
        font-size: 14px;
        line-height: 1.4;
        overflow-y: auto;       /* 内容超多时才出滚动条 */
    }

    .chatInput::placeholder {
        font-size: 14px;
        color: #cccccc;
    }

    .other {
        padding: 5px;
        min-height: 30px;
        border-radius: 5px;
        max-width: 300px;
        border: 1px solid #cccccc;
        word-break: break-all;
    }

    .self {
        padding: 5px;
        min-height: 30px;
        border-radius: 5px;
        max-width: 300px;
        border: 1px solid #95EC69;
        background-color: #95EC69;
        word-break: break-all;
    }

    .right-menu {
        position: fixed;
        background: #fff;
        border: 1px solid #ddd;
        border-radius: 4px;
        padding: 5px 0;
        margin: 0;
        list-style: none;
        font-size: 14px;
        box-shadow: 0 2px 8px rgba(0,0,0,.15);
        z-index: 999;
    }

    .right-menu li {
        padding: 6px 15px;
        cursor: pointer;
    }

    .right-menu li:hover {
        background: #f5f5f5;
    }

    .friend_list {
        position: relative;
        display: flex;
        align-items: center;
        padding: 5px;
        cursor: pointer;
    }

    .nav-item-default {
        transition-property: background-color, color;
		transition-duration: 0.3s;
        border-radius: 5px;
	}

	.nav-item-default:hover {
		background-color: #f7f8fa;
		color: #1e80ff;
	}

	.nav-item-active {
		background-color: #f1f8ff;
		color: #1e80ff;
        border-radius: 5px;
	}

    .noReadCount {
        position: absolute;
        top: 5px;
        right: 5px;
    }

    .lastMsg {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 100px;
    }

    .splitter{
        cursor: row-resize;   // 鼠标变成上下箭头
        user-select: none;    // 禁止选中
    }

    .input-area{
        display: flex;
        flex-direction: column;
        overflow: hidden;
        min-height: 200px;
    }

    .send-bar {
        flex: 0 0 auto;
        display: flex;
        justify-content: flex-end;
        align-items: center;
    }

    .empty-chat-bg {
        flex: 1 1 0;
        min-height: 500px;
        background-image: url('@/assets/images/logo.png');
        background-size: 100px 100px;
        background-position: center;
        background-repeat: no-repeat;
        opacity: 0.3;
    }

    // 图片预览样式
    .image-preview-wrapper {
        display: flex;
        justify-content: flex-start;
    }

    .image-preview {
        display: inline-block;
        border: 1px solid #e6e8eb;
        border-radius: 4px;
        padding: 4px;
        background: #f8f9fa;
    }

    .preview-image {
        max-width: 200px;
        max-height: 150px;
        border-radius: 2px;
        display: block;
    }

    .preview-actions {
        position: absolute;
        bottom: 8px;
        right: 8px;
    }

    // 聊天图片样式
    .chat-image {
        max-width: 200px;
        max-height: 150px;
        border-radius: 4px;
        cursor: pointer;
        transition: opacity 0.3s;
    }

    .chat-image:hover {
        opacity: 0.8;
    }

    // 调整消息气泡样式以适应图片
    .other, .self {
        max-width: 400px; // 增加最大宽度以容纳图片
    }
    .image-message {
        max-width: 300px;
    }

    .chat-image {
        max-width: 100%;
        max-height: 200px;
        border-radius: 4px;
        cursor: pointer;
        transition: opacity 0.3s;
        border: 1px solid #e6e8eb;
    }

    .chat-image:hover {
        opacity: 0.9;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    }

    // 调整消息气泡以适应图片
    .other, .self {
        max-width: 400px;
        padding: 8px;
    }

    // 确保图片消息的样式正确
    .self .image-message {
        text-align: right;
    }

    .other .image-message {
        text-align: left;
    }
    // 图片预览弹窗样式
    .image-preview-modal {
        .el-message-box__header {
            padding: 10px;
        }
        .el-message-box__content {
            padding: 0;
        }
    }
</style>
